<?php

namespace App\Http\Controllers\RbhMiniProgram;

use App\Exceptions\BusinessException;
use App\Http\Controllers\Controller;
use App\Http\Resources\UserModelResource;
use App\Models\UserModel;
use App\Utils\ApiResponse;
use App\Utils\ResponseEnum;
use App\Utils\Tools\CheckEmptyAndValid;
use App\Utils\VerifyRequestInput;
use App\Utils\WeChat\RbhMiniProgramWechat;
use App\Utils\WeChat\RbhSupplyMiniProgramWechat;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;

class MiniProgramUserController extends Controller
{
    use ApiResponse, VerifyRequestInput;

    /**
     * 获取openid
     * @return JsonResponse
     * @throws BusinessException
     * @throws ClientExceptionInterface
     * @throws DecodingExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ServerExceptionInterface
     * @throws TransportExceptionInterface
     */
    public function getUserOpenId(): JsonResponse
    {
        $wechat = new RbhMiniProgramWechat();
        $openid = $wechat->getUserOpenId($this->verifyString('code'));
        if (!$openid)
            return $this->fail(ResponseEnum::USER_WECHAT_LOGIN_ERROR);
        $user = UserModel::where('user_openid', $openid)->first();
        return $this->success($user ? new UserModelResource($user) : ['openid' => $openid]);
    }

    /**
     * 获取用户手机号
     * @return JsonResponse
     * @throws BusinessException
     * @throws TransportExceptionInterface
     */
    public function getUserMobile(): JsonResponse
    {
        $code = $this->verifyString('code');
        $this->verifyString('openid');
        $WeChat = new RbhSupplyMiniProgramWechat();
        $data = $WeChat->getUserMobile($code);
        if (!$data)
            return $this->fail(ResponseEnum::USER_WECHAT_MOBILE_ERROR);
        $mobile = $data->purePhoneNumber;
        return $this->success(['mobile' => $mobile]);
    }

    /**
     * 用户登录，保存用户信息
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function doSave(Request $request): JsonResponse
    {
        $openId = $this->verifyString('openid');
        $mobile = $this->verifyString('mobile');
        $verify = $this->verifyString('verify');
        if (CheckEmptyAndValid::checkVerify($mobile, $verify) === false)
            return $this->fail(ResponseEnum::USER_SERVICE_VERIFY_INVALID);
        $user = $this->handleUserCreateOrUpdate($mobile, $openId);
        if (!$user)
            return $this->fail(ResponseEnum::CLIENT_NOT_FOUND_HTTP_ERROR);
        return $this->success($user);
    }

    /**
     * 获取用户信息
     * @return JsonResponse
     * @throws BusinessException
     */
    public function getUserInfo(): JsonResponse
    {
        $openid = $this->verifyString('openid');
        $user = UserModel::where('user_openid', $openid)->first();
        return $this->success($user ? new UserModelResource($user) : ['openid' => $openid]);
    }

    /**
     * 处理用户创建或更新
     * @param $mobile
     * @param $openId
     * @return mixed
     */
    private function handleUserCreateOrUpdate($mobile, $openId): mixed
    {
        $user = UserModel::where('username', $mobile)->first();
        if (!$user)
            $user = $this->handleCreateUser($mobile, $mobile, $openId);
        else {
            if (!$user->user_openid) {
                $user->user_openid = $openId;
                $user->save();
            }
        }
        return $user;
    }

    /**
     * 创建用户
     * @param $username
     * @param $mobile
     * @param string $openId
     * @return mixed
     */
    private function handleCreateUser($username, $mobile, string $openId = ''): mixed
    {
        return UserModel::create([
            'uuid'          => uniqid(),
            'username'      => $username,
            'mobile'        => $mobile,
            'user_openid'   => $openId,
        ]);
    }
}
